#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    resizeUi.init(600,400);
    resizeUi.addInfo(ui->info1);
    resizeUi.addInfo(ui->info2);
    resizeUi.addInfo(ui->inputDev);
    resizeUi.addInfo(ui->outputDev);
    resizeUi.addInfo(ui->pushButton);
    resizeUi.addInfo(ui->pushButton_2);
    resizeUi.addInfo(ui->pushButton_3);

    resizeUi.resizes(1080,1800);


    inputDevs =  QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
    outputDevs =  QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);

    foreach(QAudioDeviceInfo i,inputDevs)
        ui->inputDev->addItem(i.deviceName());

    foreach(QAudioDeviceInfo i,outputDevs)
        ui->outputDev->addItem(i.deviceName());

    ui->pushButton_2->setEnabled(false);
    ui->pushButton->setEnabled(false);


    format.setSampleRate(48000);
    format.setChannelCount(2);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);

    QDir::setCurrent(tr("/mnt/sdcard"));
    pcmname="/storage/emulated/0/test.raw";
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::savePCM2WAV(QString src , QString dst)
{
    // 开始设置WAV的文件头
    // 这里具体的数据代表什么含义请看上一篇文章（Qt之WAV文件解析）中对wav文件头的介绍
    WAVFILEHEADER WavFileHeader;
    qstrcpy(WavFileHeader.RiffName, "RIFF");
    qstrcpy(WavFileHeader.WavName, "WAVE");
    qstrcpy(WavFileHeader.FmtName, "fmt ");
    qstrcpy(WavFileHeader.DATANAME, "data");

    // 表示 FMT块 的长度
    WavFileHeader.nFmtLength = 16;
    // 表示 按照PCM 编码;
    WavFileHeader.nAudioFormat = 1;
    // 声道数目;
    WavFileHeader.nChannleNumber = format.channelCount();
    // 采样频率;
    WavFileHeader.nSampleRate = format.sampleRate();
    // 每次采样得到的样本数据位数;
    WavFileHeader.nBitsPerSample = format.sampleSize();

    // nBytesPerSample 和 nBytesPerSecond这两个值通过设置的参数计算得到;
    // 数据块对齐单位(每个采样需要的字节数 = 通道数 × 每次采样得到的样本数据位数 / 8 )
    WavFileHeader.nBytesPerSample = WavFileHeader.nChannleNumber * WavFileHeader.nBitsPerSample / 8;
    // 波形数据传输速率
    // (每秒平均字节数 = 采样频率 × 通道数 × 每次采样得到的样本数据位数 / 8  = 采样频率 × 每个采样需要的字节数 )
    WavFileHeader.nBytesPerSecond = WavFileHeader.nSampleRate * WavFileHeader.nBytesPerSample;


    QFile pcmFile(src);
    QFile wavFile(dst);

    if (!pcmFile.open(QIODevice::ReadWrite))
    {
        return ;
    }
    if (!wavFile.open(QIODevice::WriteOnly))
    {
        return ;
    }

    int nSize = sizeof(WavFileHeader);
    qint64 nFileLen = pcmFile.bytesAvailable();

    WavFileHeader.nRiffLength = nFileLen - 8 + nSize;
    WavFileHeader.nDataLength = nFileLen;

    // 先将wav文件头信息写入，再将音频数据写入;
    wavFile.write((char *)&WavFileHeader, nSize);
    wavFile.write(pcmFile.readAll());

    pcmFile.close();
    wavFile.close();
}

void MainWindow::on_pushButton_3_clicked()
{
    pcmname = QFileDialog::getSaveFileName();

    if(pcmname.size()>1)
    {
        ui->pushButton_2->setEnabled(true);
        ui->pushButton->setEnabled(true);
        ui->info2->setText(pcmname);
    }
    else
        ui->info2->setText(tr("file load failed"));
}

void MainWindow::on_pushButton_clicked()
{
    if(!isRecord)
    {
        ui->pushButton->setText(tr("stop"));
        isRecord=true;
        ui->inputDev->setEnabled(false);

        QAudioDeviceInfo info;
//        info = inputDevs.at(0);
        info = inputDevs.at(ui->inputDev->currentIndex());

        if (!info.isFormatSupported(format))
        {
           qWarning()<<"default format not supported try to use nearest";
           format = info.nearestFormat(format);
        }

        audioIn = new QAudioInput(info, format, this);

        outputFile.setFileName(pcmname);
        if(!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
            ui->info2->setText(tr("open failed!"));
        else
            audioIn->start(&outputFile);
    }
    else
    {
        ui->inputDev->setEnabled(true);
        ui->pushButton->setEnabled(true);
        audioIn->stop();
        outputFile.close();

        QString wavname=pcmname+".wav";
        savePCM2WAV(pcmname,wavname);

        ui->pushButton->setText(tr("start"));
        isRecord=false;

        delete audioIn;
    }
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    resizeUi.resizes(this->width(),this->height());
}

void MainWindow::on_pushButton_2_clicked()
{
    if(!isPlay)
    {
        inputFile.setFileName(pcmname);
        inputFile.open(QIODevice::ReadOnly);

        ui->outputDev->setEnabled(false);

        QAudioDeviceInfo info;
//        info = outputDevs.at(0);
        info = outputDevs.at(ui->outputDev->currentIndex());
        qDebug() <<"info:"<<info.deviceName()<<endl;

        if (!info.isFormatSupported(format))
        {
             qWarning()<<"raw audio format not supported by backend, cannot play audio.";
             return;
        }

        outAudio = new QAudioOutput(format, this);
        outAudio->start(&inputFile);
        connect(outAudio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State)));

        ui->pushButton_2->setText(tr("stop"));
        isPlay=true;
    }
    else
    {
        ui->outputDev->setEnabled(true);
        ui->pushButton_2->setText(tr("play"));
        isPlay=false;
        outAudio->stop();
        delete outAudio;
    }
}

void MainWindow::finishedPlaying(QAudio::State state)
{
    if(state == QAudio::IdleState)
    {
         outAudio->stop();
         inputFile.close();
         ui->outputDev->setEnabled(true);
         ui->pushButton_2->setText(tr("play"));
         isPlay=false;
         delete outAudio;
    }
}
